<?php if(!defined('DEBUG')) die;

/**
 * Frog CMS - Content Management Simplified. <http://www.madebyfrog.com>
 * Copyright (C) 2008 Philippe Archambault <philippe.archambault@gmail.com>
 * Copyright (C) 2008 Martijn van der Kleijn <martijn.niji@gmail.com>
 * Copyright (C) 2008 Maslakov Alexander <jmas.ukraine@gmail.com>
 *
 * This file is part of Frog CMS.
 *
 * Frog CMS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Frog CMS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Frog CMS.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Frog CMS has made an exception to the GNU General Public License for plugins.
 * See exception.txt for details and the full text.
 */

/**
 * @package frog
 * @subpackage helpers
 *
 * @author Maslakov Alexandr <jmas.ukraine@gmail.com>
 * @version 0.1
 * @license http://www.gnu.org/licenses/gpl.html GPL License
 * @copyright Maslakov Alexander, 2010
 */

/*
	Class Dir
	Working with directories
*/
class Dir
{
	private $_path = null;
	private $_files = array();
	private $_dirs = array();
	
	
	// Directory path as constructor param
	public function __construct( $path, $sort_callback = 'natsort' )
	{
		if( is_dir($path) )
		{
			// Set directory path
			$this->_path = str_replace('\\', '/', realpath($path));
			
			
			// Read directory items
			$dir = opendir( $this->_path );
			
			while( $item = readdir( $dir ) )
			{
				if( strpos($item, '.') !== 0 )
				{
					if( is_dir( $this->_path .'/'. $item ) )
					{
						$this->_dirs[] = $item;
					}
					else
					{
						$this->_files[] = $item;
					}
				}
			}
			
			// Sorting
			call_user_func_array( $sort_callback, array($this->_dirs) );
			call_user_func_array( $sort_callback, array($this->_files) );
		}
		else
		{
			throw new Exception('This is not valid directory path!');
		}
	}
	
	
	// Return all subdirectories of this directory
	public function getDirs()
	{
		$dirs = array();
		
		if( empty($dirs) )
		{
			foreach( $this->_dirs as $dir_name )
			{
				$dirs[] = new Dir( $this->_path .'/'. $dir_name );
			}
		}
		
		return $dirs;
	}
	
	
	// Return all files of this directory
	public function getFiles()
	{
		$files = array();
		
		if( empty($files) )
		{
			foreach( $this->_files as $file_name )
			{
				$ext = preg_replace( '/^.+\./', '', $file_name );
			
				$class_name = 'DirFile';
				
				switch( $ext )
				{
					case 'jpg':
					case 'jpeg':
					case 'gif':
					case 'png':
						$class_name = 'DirFileImage';
						break;					
				}
				
				$files[] = new $class_name( $this->_path .'/'. $file_name );
			}
		}
		
		return $files;
	}
	
	
	// Remove dir and subdirs
	public function remove()
	{
		// Remove all directory files
		if( !empty( $this->_files ) )
		{
			foreach( $this->getFiles() as $file )
			{
				if( !$file->remove() )
					return false;
			}
		}
		
		// Remove all sub directories
		if( !empty( $this->_dirs ) )
		{
			foreach( $this->getDirs() as $dir )
			{
				if( !$dir->remove() )
					return false;
			}
		}
		
		return @rmdir( $this->_path );
	}
	
	
	// Short permistions
	public function getPermsShort()
	{
	    $perms = $this->getPerms();

		//$p = decoct($perms);
	
		return substr(sprintf('%o', $perms), -4, 4);
	    //return (strlen($p) > 4 ? substr($p, -4) : $p);
	}
	
	
	// Return file permissions
	public function getPerms()
	{
		return fileperms( $this->_path );
	}
	
	
	// Return file permissions as humannized string
	public function getPermsString()
	{
		$perms = $this->getPerms( $this->_path );
	
		if (($perms & 0xC000) == 0xC000) {
		    // Socket
		    $info = 's';
		} elseif (($perms & 0xA000) == 0xA000) {
		    // Symbolic Link
		    $info = 'l';
		} elseif (($perms & 0x8000) == 0x8000) {
		    // Regular
		    $info = '-';
		} elseif (($perms & 0x6000) == 0x6000) {
		    // Block special
		    $info = 'b';
		} elseif (($perms & 0x4000) == 0x4000) {
		    // Directory
		    $info = 'd';
		} elseif (($perms & 0x2000) == 0x2000) {
		    // Character special
		    $info = 'c';
		} elseif (($perms & 0x1000) == 0x1000) {
		    // FIFO pipe
		    $info = 'p';
		} else {
		    // Unknown
		    $info = 'u';
		}

		// Owner
		$info .= (($perms & 0x0100) ? 'r' : '-');
		$info .= (($perms & 0x0080) ? 'w' : '-');
		$info .= (($perms & 0x0040) ?
		            (($perms & 0x0800) ? 's' : 'x' ) :
		            (($perms & 0x0800) ? 'S' : '-'));

		// Group
		$info .= (($perms & 0x0020) ? 'r' : '-');
		$info .= (($perms & 0x0010) ? 'w' : '-');
		$info .= (($perms & 0x0008) ?
		            (($perms & 0x0400) ? 's' : 'x' ) :
		            (($perms & 0x0400) ? 'S' : '-'));

		// World
		$info .= (($perms & 0x0004) ? 'r' : '-');
		$info .= (($perms & 0x0002) ? 'w' : '-');
		$info .= (($perms & 0x0001) ?
		            (($perms & 0x0200) ? 't' : 'x' ) :
		            (($perms & 0x0200) ? 'T' : '-'));
		
		return $info;
	}
	
	
	// Return directory path
	public function getPath()
	{
		return $this->_path;
	}
	
	
	// FrogCMS path shorted
	public function getPathShort( $dir_name = PUBLIC_FILES )
	{
		return substr($this->_path, strpos($this->_path, $dir_name), strlen($this->_path));
	}
	
	
	// Return directory path
	public function __toString()
	{
		return $this->_path;
	}
	
	
	// ID hash
	public function getId()
	{
		return md5($this->_path);
	}
	
	
	// Check for childrens (directories or files)
	public function hasChildrens( $only_dirs = false )
	{
		if( $only_dirs )
			return !(empty($this->_dirs));
		else
			return !(empty($this->_dirs) && empty($this->_files));
	}
	
	
	// Check for files
	public function hasFiles()
	{
		return !empty($this->_files);
	}
	
	
	// Get directory name
	public function getName()
	{
		return substr($this->_path, strrpos($this->_path, '/')+1, strlen($this->_path));
	}
} // end



/*
	Class DirFile
	Workin with files
*/
class DirFile
{
	private $_path = null;
	
	
	// File path as constructor param
	public function __construct( $path )
	{
		if( is_file( $path ) )
		{
			$this->_path = str_replace('\\', '/', $path);
		}
		else
		{
			throw new Exception('This is not valid file path!');
		}
	}
	
	
	// Get file size
	public function getSize()
	{
		return filesize( $this->_path );
	}
	
	
	// Short permistions
	public function getPermsShort($octal = true)
	{
	    $perms = $this->getPerms();

	    $cut = $octal ? 2 : 3;

	    return substr(decoct($perms), $cut);
	}
	
	
	// Return file permissions
	public function getPerms()
	{
		return fileperms( $this->_path );
	}
	
	
	// Return file permissions as humannized string
	public function getPermsString()
	{
		$perms = $this->getPerms( $this->_path );
	
		if (($perms & 0xC000) == 0xC000) {
		    // Socket
		    $info = 's';
		} elseif (($perms & 0xA000) == 0xA000) {
		    // Symbolic Link
		    $info = 'l';
		} elseif (($perms & 0x8000) == 0x8000) {
		    // Regular
		    $info = '-';
		} elseif (($perms & 0x6000) == 0x6000) {
		    // Block special
		    $info = 'b';
		} elseif (($perms & 0x4000) == 0x4000) {
		    // Directory
		    $info = 'd';
		} elseif (($perms & 0x2000) == 0x2000) {
		    // Character special
		    $info = 'c';
		} elseif (($perms & 0x1000) == 0x1000) {
		    // FIFO pipe
		    $info = 'p';
		} else {
		    // Unknown
		    $info = 'u';
		}

		// Owner
		$info .= (($perms & 0x0100) ? 'r' : '-');
		$info .= (($perms & 0x0080) ? 'w' : '-');
		$info .= (($perms & 0x0040) ?
		            (($perms & 0x0800) ? 's' : 'x' ) :
		            (($perms & 0x0800) ? 'S' : '-'));

		// Group
		$info .= (($perms & 0x0020) ? 'r' : '-');
		$info .= (($perms & 0x0010) ? 'w' : '-');
		$info .= (($perms & 0x0008) ?
		            (($perms & 0x0400) ? 's' : 'x' ) :
		            (($perms & 0x0400) ? 'S' : '-'));

		// World
		$info .= (($perms & 0x0004) ? 'r' : '-');
		$info .= (($perms & 0x0002) ? 'w' : '-');
		$info .= (($perms & 0x0001) ?
		            (($perms & 0x0200) ? 't' : 'x' ) :
		            (($perms & 0x0200) ? 'T' : '-'));
		
		return $info;
	}
	
	
	// Return file extension
	public function getExt()
	{
		return preg_replace( '/^.+\./', '', $this->_path );
	}
	
	
	// Remove file
	public function remove()
	{
		return @unlink( $this->_path );
	}
	
	
	// Return directory path
	public function getPath()
	{
		return $this->_path;
	}
	
	
	// FrogCMS path shorted
	public function getPathShort( $dir_name = PUBLIC_FILES )
	{
		return substr($this->_path, strpos($this->_path, $dir_name), strlen($this->_path));
	}
	
	
	// Return file path
	public function __toString()
	{
		return $this->_path;
	}
	
	
	// ID hash
	public function getId()
	{
		return md5($this->_path);
	}
	
	
	// Get file name
	public function getName()
	{
		return substr($this->_path, strrpos($this->_path, '/')+1, strlen($this->_path));
	}
	
	
	// Only dir path
	public function getDirPath()
	{
		return substr($this->getPathShort(), 0, strrpos($this->getPathShort(), '/')+1);
	}
} // end



/*
	DirFileImage
*/
/*
* File: SimpleImage.php
* Author: Simon Jarvis
* Copyright: 2006 Simon Jarvis
* Date: 08/11/06
* Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
* 
* This program is free software; you can redistribute it and/or 
* modify it under the terms of the GNU General Public License 
* as published by the Free Software Foundation; either version 2 
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details: 
* http://www.gnu.org/licenses/gpl.html
*
*/
class DirFileImage extends DirFile
{
	private $image;
	private $image_type;
	
	
	public function __construct( $file_path )
	{
		parent::__construct( $file_path );
		
		$this->load( $file_path );
	}
	
	
	public function __toString()
	{
		$this->output();
	}
	
	
	function load( $filename )
	{
		$image_info = getimagesize( $filename );
		$this->image_type = $image_info[2];

		if( $this->image_type == IMAGETYPE_JPEG )
		{
			$this->image = imagecreatefromjpeg( $filename );
		}
		elseif( $this->image_type == IMAGETYPE_GIF )
		{
			$this->image = imagecreatefromgif( $filename );
		}
		elseif( $this->image_type == IMAGETYPE_PNG )
		{
			$this->image = imagecreatefrompng( $filename );
		}
	}


	function save( $filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null )
	{
		if( $permissions != null)
		{
			chmod( $filename, $permissions );
		}
		
		if( $image_type == IMAGETYPE_JPEG )
		{
			return imagejpeg( $this->image, $filename, $compression );
		}
		elseif( $image_type == IMAGETYPE_GIF )
		{
			return imagegif( $this->image, $filename);
		}
		elseif( $image_type == IMAGETYPE_PNG )
		{
			return imagepng( $this->image, $filename );
		}
	}
	
	
	function output( $image_type = IMAGETYPE_JPEG )
	{
		switch( $image_type )
		{
			case IMAGETYPE_JPEG: header('Content-type: image/jpg'); break;
			case IMAGETYPE_GIF:  header('Content-type: image/gif'); break;
			case IMAGETYPE_PNG:  header('Content-type: image/png'); break;
		}
		
		if( $image_type == IMAGETYPE_JPEG )
		{
			imagejpeg($this->image);
		}
		elseif( $image_type == IMAGETYPE_GIF )
		{
			imagegif($this->image);
		}
		elseif( $image_type == IMAGETYPE_PNG )
		{
			imagepng($this->image);
		}   
	}


	function getWidth()
	{
		return imagesx($this->image);
	}


	function getHeight()
	{
		return imagesy( $this->image );
	}


	function resizeToHeight( $height )
	{
		$ratio = $height / $this->getHeight();
		$width = $this->getWidth() * $ratio;
		
		$this->resize($width,$height);
	}


	function resizeToWidth( $width )
	{
		$ratio 	= $width / $this->getWidth();
		$height = $this->getheight() * $ratio;
		
		$this->resize( $width, $height );
	}


	function scale( $scale )
	{
		$width 	= $this->getWidth() * ($scale / 100);
		$height = $this->getheight() * ($scale / 100);
		
		$this->resize( $width, $height );
	}


	function resize( $width, $height )
	{		
		$new_width  = $this->getWidth();
		$new_height = $this->getHeight();
		
		$new_image = imagecreatetruecolor( $width, $height );
		imagecopyresampled( $new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight() );
		
		$this->image = $new_image;
	}
	

	function thumb( $width, $height, $x1, $y1, $x2, $y2 )
	{
		$new_width  = $x2 - $x1;
		$new_height = $y2 - $y1;
		
		// Coefficient that tell how crop area higer or smaller than thumb
		$k = $new_width / $width;
		
		$new_image = imagecreatetruecolor( $width, $height );
		imagecopyresampled( $new_image, $this->image, 0, 0, $x1 * $k, $y1 * $k, $width, $height, $new_width * $k, $new_height * $k );
		
		$this->image = $new_image;
	}
} // end

?>